from fileinput import filename
import struct
#import binascii
#from sys import byteorder

#char 8 bit, b.
#uchar 8 bit, B.
#text byte, char with value within the ASCII range of 0x20 through 0x7E.
#ushort 16 bit, H.
#ulong 32 bit, I.
#double ulong 64 bit, Q.
#ID 32 bit, I
#   a concatenation of four printable ASCII characters in the range
#   ' ' (space, 0x20) through '~'(0x7E). Space (0x20) cannot precede
#   printing characters; trailing spaces are allowed. Control characters are
#   forbidden. The ID is case sensitive. Therefore ID's can be compared
#   using a simple 32-bit equality check.
#pad byte, char with value 0, used for making chunks an even length.
#Struct, Set of variables forming one entity.

#typedef struct {
#   ID ckID; // chunkid
#   double ulong ckDataSize; // chunk data size, in bytes
#   uchar ckData[]; // data
#} Chunk;

#typedef struct {
#   ID ckID; // 'FRM8'
#   double ulong ckDataSize; // FORM's data size, in bytes
#   ID formType; // 'DSD '
#   Chunk frm8Chunks[]; // local chunks
#} FormDSDChunk;

# ‘>’ 大端字节序，1字节对齐
FormDSDChunkHeaderFmt = '>IQI'
FormDSDChunkHeaderSize = struct.calcsize(FormDSDChunkHeaderFmt)

#typedef struct {
#   ID ckID; // 'FVER'
#   double ulong ckDataSize; // 4
#   ulong version; // 0x01050000 version 1.5.0.0 DSDIFF
#} FormatVersionChunk;
#ckDataSize is the size of the data portion of the chunk, in bytes. It does not include the 12
#bytes used by ckID and ckDataSize. For this chunk, ckDataSize is 4.
FVERHeaderFmt = '>IQI'
FVERHeaderSize = struct.calcsize(FVERHeaderFmt)

#ypedef struct {
#   ID ckID; // 'PROP'
#   double ulong ckDataSize;
#   ID propType; // 'SND '
#   Chunk propChunks[]; // local chunks
#} PropertyChunk;
#ckID is always 'PROP'. It indicates that this is the property container chunk (of type
#propType).
#ckDataSize is the summation of the sizes of all local property chunks plus the size of
#propType. It does not include the 12 bytes used by ckID and ckDataSize.

PROPHeaderFmt = '>IQ'
PROPHeaderSize = struct.calcsize(PROPHeaderFmt)

#   ID propType; // 'SND '
#typedef struct {
#   ID ckID; // 'FS '
#   double ulong ckDataSize; // 4
#   ulong sampleRate; // sample rate in [Hz]
#} SampleRateChunk;
#typedef struct {
#   ID ckID; // 'CHNL'
#   double ulong ckDataSize;
#   ushort numChannels; // number of audio channels
#   ID chID[]; // channels ID's
#} ChannelsChunk;
#typedef struct {
#   ID ckID; // 'CMPR'
#   double ulong CkDataSize;
#   ID  compressionType; // compression ID code
#   uchar Count; // length of the compression name
#   text byte compressionName[]; // human readable type name
#} CompressionTypeChunk;
#typedef struct {
#   ID ckID;// 'LSCO'
#   double ulong ckDataSize; // 2
#   ushort lsConfig; // loudspeaker configuration
#} LoudspeakerConfigurationChunk;

PROPBodyFmt = '>IIQIIQHIIIQIB15BIQH'
PROPBodySize = struct.calcsize(PROPBodyFmt)

#typedef struct {
#   ID ckID; // 'DSD '
#   double ulong ckDataSize;
#   uchar DSDsoundData[]; // (interleaved) DSD data
#} DSDSoundDataChunk;

DSDDataChunkHeaderFmt = '>IQ'
DSDDataChunkHeaderSize = struct.calcsize(DSDDataChunkHeaderFmt)

#typedef struct {
#   ID ckID; // 'DIIN'
#   double ulong ckDataSize;
#   Chunk EmChunks[]; // container
#} EditedMasterInformationChunk;

DIINHeaderFmt = '>IQ'
DIINHeaderSize = struct.calcsize(DIINHeaderFmt)

#typedef struct {
#   ID ckID; // 'MARK'
#   double ulong ckDataSize;
#   ushort  hours; // marker position in hours
#   uchar minutes; // marker position in minutes
#   uchar seconds; // marker position in seconds
#   ulong samples; // marker position in samples
#   Long offset; // marker offset in samples
#   ushort markType; // type of marker
#   ushort markChannel; // channel reference
#   ushort TrackFlags; // special purpose flags
#   ulong count; // string length
#   Text byte markerText[]; // description
#} MarkerChunk;


MARKHeaderFmt = '>IQHBBIiHHHI'
MARKHeaderSize = struct.calcsize(MARKHeaderFmt)

#typedef struct {
#   ID ckID; // 'DIAR'
#   double ulong ckDataSize;
#   ulong count; // string length
#   text byte artistText[];// description
#} ArtistChunk;

DIARHeaderFmt = '>IQI'
DIARHeaderSize = struct.calcsize(DIARHeaderFmt)

#typedef struct {
#   ID ckID; // 'DITI'
#   double ulong ckDataSize; 
#   ulong count; // string length
#   text byte titleText[]; // description
#} TitleChunk;

DITIHeaderFmt = '>IQI'
DITIHeaderSize = struct.calcsize(DITIHeaderFmt)

#typedef struct {
#   ID ckID; // 'COMT'
#   double ulong ckDataSize; 
#   ushort numComments; // number of comments
#   Comment comments[]; // the concatenated comments
#} CommentsChunk;

COMTHeaderFmt = '>IQH'
COMTHeaderSize = struct.calcsize(COMTHeaderFmt)

#typedef struct{
#   ushort timeStampYear; // creation year
#   uchar TimeStampMonth; // creation month
#   uchar timeStampDay; // creation day
#   uchar timeStampHour; // creation hour
#   uchar timeStampMinutes; // creation minutes
#   ushort cmtType; // comment type
#   ushort cmtRef; // comment reference
#   ulong count; // string length
#   text byte commentText[]; // text
#} Comment;

COMTBodyFmt = '>HBBBBHHI'
COMTBodySize = struct.calcsize(COMTBodyFmt)

#typedef struct {
#   ID ckID; // 'ID3 '
#   double ulong ckDataSize; 
#   chunk ID3tag[]; // ID3tag内容
#} ID3Chunk;

#typedef ID3_HEADER {
#    uint8_t id3_identifier[3]; 头部标识。占3个字节，由字符ID3组成，表示这是一个ID3v2的标签; 
#    uint8_t id3_version; 主版本号。版本号 ID3V2.3 就记录 3
#    uint8_t id3_revision;
#    uint8_t id3_flags;
#    uint32_t id3_size;
#} ID3_HEADER_t;
ID3ChunkHeaderFmt = '>IQ'
ID3ChunkHeaderSize = struct.calcsize(ID3ChunkHeaderFmt)
ID3TagHeaderFmt = '>3BBBBI'
ID3TagHeaderSize = struct.calcsize(ID3TagHeaderFmt)

#typedef ID3_FRAME {
#    uint8_t frame_id[4];
#    uint32_t frame_size;
#    uint16_t frame_flags;
#} ID3_FRAME_t;
ID3FrameHeaderFmt = '>4BIH'
ID3FrameHeaderSize = struct.calcsize(ID3FrameHeaderFmt)


